package com.lx.algorithm.code.xly3.class04;

import com.lx.algorithm.Utils;

/**
 * Description:
 * Copyright:   Copyright (c)2019
 * Company:     zefu
 *
 * @author: 张李鑫
 * @version: 1.0
 * Create at:   2022-01-12 15:28:47
 * <p>
 * Modification History:
 * Date         Author      Version     Description
 * ------------------------------------------------------------------
 * 2022-01-12     张李鑫                     1.0         1.0 Version
 */
public class Code07 {


    /**
     * Code07_SubMatrixMaxSum
     * <p>
     * 给定一个整型矩阵，返回子矩阵的最大累计和。
     */
    public static int subMatrixMaxSum(int[][] Matrix) {
        if (Matrix == null || Matrix.length == 0) {
            return 0;
        }
        int max = Integer.MIN_VALUE;
        int[] arr;

        //核心思路是以每一层为底的时候求出当前累加最大矩阵
        //用数组上下累加的方式计算矩阵
        for (int t = 0; t < Matrix.length; t++) {
            arr = new int[Matrix[t].length];
            for (int i = t; i >= 0; i--) {
                for (int j = 0; j < Matrix[i].length; j++) {
                    arr[j] = arr[j] + Matrix[i][j];
                }
                max = Math.max(max, maxSum(arr));
            }
        }
        return max;
    }

    public static int maxSum(int[] arr) {
        int max = Integer.MIN_VALUE;
        int sum = 0;
        for (int i = 0; i < arr.length; i++) {
            sum += arr[i];
            max = Math.max(sum, max);
            sum = Math.max(0, max);
        }
        return max;
    }

    public static void main(String[] args) {
        int size = 1000;
        for (int i = 0; i < 1000; i++) {
            int[][] ints = Utils.generateRandomMatrix(size, 20);

            if (subMatrixMaxSum(ints) !=
                    maxSum(ints)) {
                System.out.println("error");
                break;
            }
        }
    }


    public static int maxSum(int[][] m) {
        if (m == null || m.length == 0 || m[0].length == 0) {
            return 0;
        }
        int max = Integer.MIN_VALUE;
        int cur = 0;
        int[] s = null;
        for (int i = 0; i != m.length; i++) { // 开始的行号i
            s = new int[m[0].length]; //
            for (int j = i; j != m.length; j++) { // 结束的行号j，i~j行是我讨论的范围
                cur = 0;
                for (int k = 0; k != s.length; k++) {
                    s[k] += m[j][k];
                    cur += s[k];
                    max = Math.max(max, cur);
                    cur = cur < 0 ? 0 : cur;
                }
            }
        }
        return max;
    }

}
